package com.yiyaOvo.cloudDisk;

import com.yiyaOvo.cloudDisk.pojo.FileItem;
import com.yiyaOvo.cloudDisk.utils.FileUtils;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;

import static com.yiyaOvo.cloudDisk.utils.FileUtils.*;

/**
 * User: yiyaOvo
 * Date: 2021/5/23
 * Time: 15:06
 * role: server
 */
public class Server {

    /**
     * handling files query
     * @param inputStream
     * @param outputStream
     */
    private void handlerListFiles (DataInputStream inputStream, DataOutputStream outputStream) throws IOException {
        // get uploaded files list
        List<FileItem> uploadFiles = getUploadFiles();
        String json = listToJSON(uploadFiles);
        // send it to client
        outputStream.writeUTF(json);
    }

    /**
     * handling files upload
     * @param inputStream
     * @param outputStream
     */
    private void handlerFileUpload (DataInputStream inputStream, DataOutputStream outputStream) throws IOException {
        String fileName = inputStream.readUTF();
        if ("error".equals(fileName)) {
            System.out.println("upload error!!!!!!");
            return;
        }
        FileOutputStream fileOutputStream = new FileOutputStream(UPLOAD_DIR + "\\" + fileName);
        FileUtils.io(inputStream, fileOutputStream);
    }

    /**
     * handling files download
     * @param inputStream
     * @param outputStream
     */
    private void handlerFileDownload (DataInputStream inputStream, DataOutputStream outputStream) throws IOException {
        String fileName = inputStream.readUTF();
        // determine whether the file is selected
        if ("".equals(fileName)) {
            System.out.println("file is not selected!!");
            return;
        }

        File file = new File(UPLOAD_DIR + "\\" + fileName);
        // determine whether the file is exist in server
        if (file.exists()) {
            // if it exists, send the file name to the client
            outputStream.writeUTF(fileName);
            // read the file and sent it to client
            FileInputStream fileInputStream = new FileInputStream(file);
            FileUtils.io(fileInputStream, outputStream);
        } else {
            // if it not exists, send "error" to client
            outputStream.writeUTF("error");
            System.out.println("the file is not exist");
        }
    }

    /**
     * handling file delete
     * @param inputStream
     * @param outputStream
     */
    private void handlerFileDelete (DataInputStream inputStream, DataOutputStream outputStream) throws IOException {
        String fileName = inputStream.readUTF();
        // determine whether the file is selected
        if ("".equals(fileName)) {
            System.out.println("file is not selected!!");
            return;
        }

        File file = new File(UPLOAD_DIR + "\\" + fileName);
        // determine whether the file is exist in server
        if (file.exists()) {
            // if it exist, delete
            file.delete();
            outputStream.writeUTF("success");
        } else {
            outputStream.writeUTF("error");
            System.out.println("the file is not exist");
        }
    }

    /**
     * start server
     */
    public void start () {
        System.out.println("server have start!!!!");
        // create server socket
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            // accept client connection
            while (true) {
                Socket socket = serverSocket.accept();
                // get IO Stream
                try (DataInputStream inputStream = new DataInputStream(socket.getInputStream());
                    DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream())) {
                    // distinguish states by passing values
                    int type = inputStream.readInt();
                    System.out.println("==========================");
                    switch (type) {
                        case TYPE_LIST:
                            handlerListFiles (inputStream, outputStream);
                            System.out.printf("client %s have execute select\n", socket.getInetAddress());
                            break;
                        case TYPE_UPLOAD:
                            handlerFileUpload (inputStream, outputStream);
                            System.out.printf("client %s have execute upload\n", socket.getInetAddress());
                            break;
                        case TYPE_DOWNLOAD:
                            handlerFileDownload (inputStream, outputStream);
                            System.out.printf("client %s have execute download\n", socket.getInetAddress());
                            break;
                        case TYPE_DELETE:
                            handlerFileDelete (inputStream, outputStream);
                            System.out.printf("client %s have execute delete\n", socket.getInetAddress());
                            break;
                    }
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new Server().start();
    }
}
